package com.jl.juc.completablefuture;

import java.util.concurrent.*;

public class CompletableFutureDemo2 {


    /**
     * runAsync 使用默认线程池
     */
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        try{
            CompletableFuture.supplyAsync(() -> {
                System.out.println(Thread.currentThread().getName() + "进入111，开始获取用户信息");
                System.out.println(Thread.currentThread().getName() + "，1秒后出结果");
                int anInt = ThreadLocalRandom.current().nextInt();
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return anInt;

            }, executorService).whenComplete((v, exception)->{
                //上一步计算完成
                if(exception == null){
                    System.out.println("没有异常，获取用户成绩成功。");
                }
            }).exceptionally( e ->{
                //上一步发生异常
                e.printStackTrace();
                System.out.println("异常：" + e.getCause()+":" + e.getMessage());
                return null;
            });

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            executorService.shutdown();
        }
        System.out.println(Thread.currentThread().getName() + "先去干其他活了。");
        //使用JunitTest也得加下面的代码：如果主线程先执行完会有问题，在main方法没问题
//        TimeUnit.SECONDS.sleep(3);
    }


    /**
     * runAsync 使用默认线程池
     * @throws ExecutionException
     * @throws InterruptedException
     */
//    @Test
    public void getUserInfo() throws ExecutionException, InterruptedException {

        CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "进入，开始获取用户信息");
            int anInt = ThreadLocalRandom.current().nextInt();
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return anInt;

        }).whenComplete((v, exception)->{
            //上一步计算完成
            if(exception == null){
                System.out.println("没有异常，获取用户成绩成功。");
            }
        }).exceptionally( e ->{
            //上一步发生异常
            e.printStackTrace();
            System.out.println("异常：" + e.getCause()+":" + e.getMessage());
            return null;
        });

        System.out.println(Thread.currentThread().getName() + "先去干其他活了。");

        //main线程不要立刻结束，否则CompletableFuture默认使用的线程池会立刻关闭（作为守护线程，其他线程关闭之后，自己就没有存在的必要了）。此处暂停3秒
        //如果使用自定义线程池没有此问题了
        TimeUnit.SECONDS.sleep(3);

    }

    /**
     * runAsync 使用默认线程池
     * @throws ExecutionException
     * @throws InterruptedException
     */
//    @Test
    public void getUserScoreFromUserService() throws ExecutionException, InterruptedException {


        CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName());
            double aDouble = ThreadLocalRandom.current().nextDouble();
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return String.valueOf(aDouble);
        });

        String s = supplyAsync.get();
        System.out.println(s);
    }
}
